class Base64Util {
    // 自定义Base64字符表（与Java保持一致）
    static base64EncodeChars = [
      "A",
      "B",
      "C",
      "D",
      "E",
      "F",
      "G",
      "H",
      "I",
      "J",
      "K",
      "L",
      "M",
      "N",
      "O",
      "P",
      "Q",
      "R",
      "S",
      "T",
      "U",
      "V",
      "W",
      "X",
      "Y",
      "Z",
      "a",
      "b",
      "c",
      "d",
      "e",
      "f",
      "g",
      "h",
      "i",
      "j",
      "k",
      "l",
      "m",
      "n",
      "o",
      "p",
      "q",
      "r",
      "s",
      "t",
      "u",
      "v",
      "w",
      "x",
      "y",
      "z",
      "0",
      "1",
      "2",
      "3",
      "4",
      "5",
      "6",
      "7",
      "8",
      "9",
      "Q",
      "Z",
    ];
  
    static base64DecodeChars = null;
  
    // 初始化解码表
    static {
      this.base64DecodeChars = new Array(256).fill(-1);
      for (let i = 0; i < 64; i++) {
        this.base64DecodeChars[this.base64EncodeChars[i].charCodeAt(0)] = i;
      }
    }
  
    /**
     * 编码字节数组到Base64字符串
     * @param {Uint8Array} data
     * @returns {string}
     */
    static encode(data) {
      if (!data) return null;
  
      let result = "";
      const len = data.length;
      let i = 0;
  
      try {
        while (i < len) {
          let b1 = data[i++] & 0xff;
          if (i === len) {
            result += this.base64EncodeChars[b1 >>> 2];
            result += this.base64EncodeChars[(b1 & 0x3) << 4];
            result += "==";
            break;
          }
          let b2 = data[i++] & 0xff;
          if (i === len) {
            result += this.base64EncodeChars[b1 >>> 2];
            result +=
              this.base64EncodeChars[((b1 & 0x03) << 4) | ((b2 & 0xf0) >>> 4)];
            result += this.base64EncodeChars[(b2 & 0x0f) << 2];
            result += "=";
            break;
          }
          let b3 = data[i++] & 0xff;
          result += this.base64EncodeChars[b1 >>> 2];
          result +=
            this.base64EncodeChars[((b1 & 0x03) << 4) | ((b2 & 0xf0) >>> 4)];
          result +=
            this.base64EncodeChars[((b2 & 0x0f) << 2) | ((b3 & 0xc0) >>> 6)];
          result += this.base64EncodeChars[b3 & 0x3f];
        }
        return result;
      } catch (e) {
        return "";
      }
    }
  
    /**
     * 解码Base64字符串到字节数组
     * @param {string} str
     * @returns {Uint8Array}
     */
    static decode(str) {
      if (!str) return null;
  
      try {
        const data = new TextEncoder().encode(str);
        const len = data.length;
        const buf = [];
        let i = 0;
        let b1 = 0,
          b2 = 0,
          b3,
          b4;
  
        while (i < len) {
          // b1
          do {
            if (i >= len) break;
            b1 = this.base64DecodeChars[data[i++] & 0xff];
          } while (i < len && b1 === -1);
          if (b1 === -1) break;
  
          // b2
          do {
            if (i >= len) break;
            b2 = this.base64DecodeChars[data[i++] & 0xff];
          } while (i < len && b2 === -1);
          if (b2 === -1) break;
          buf.push((b1 << 2) | ((b2 & 0x30) >>> 4));
  
          // b3
          do {
            if (i >= len) return new Uint8Array(buf);
            b3 = data[i++] & 0xff;
            if (b3 === 61) return new Uint8Array(buf); // '='
            b3 = this.base64DecodeChars[b3];
          } while (i < len && b3 === -1);
          if (b3 === -1) break;
          buf.push(((b2 & 0x0f) << 4) | ((b3 & 0x3c) >>> 2));
  
          // b4
          do {
            if (i >= len) return new Uint8Array(buf);
            b4 = data[i++] & 0xff;
            if (b4 === 61) return new Uint8Array(buf); // '='
            b4 = this.base64DecodeChars[b4];
          } while (i < len && b4 === -1);
          if (b4 === -1) break;
          buf.push(((b3 & 0x03) << 6) | b4);
        }
        return new Uint8Array(buf);
      } catch (e) {
        return new Uint8Array([]);
      }
    }
  
    /**
     * 加密数字字符串
     * @param {string} number
     * @returns {string}
     */
    static encryptNumber(number) {
      try {
        // 验证输入是否为纯数字
        if (!number || !/^\d+$/.test(number)) {
          throw new Error("Input must be numeric");
        }
  
        // 数字到字符的映射表（与Java保持一致）
        const mapping = {
          0: "k",
          1: "p",
          2: "m",
          3: "n",
          4: "b",
          5: "v",
          6: "c",
          7: "x",
          8: "z",
          9: "l",
        };
  
        // 将数字转换为映射字符
        let mapped = "";
        for (let char of number) {
          mapped += mapping[char];
        }
  
        // Base64编码
        const bytes = new TextEncoder().encode(mapped);
        let encoded = this.encode(bytes);
  
        // 去除等号填充符
        encoded = encoded.replace(/=/g, "");
  
        // 确保长度至少为4
        if (encoded.length < 4) {
          while (encoded.length < 4) {
            encoded += "A";
          }
        }
  
        return encoded;
      } catch (e) {
        return number; // 失败时返回原始输入
      }
    }
  
    /**
     * 解密字符串为数字
     * @param {string} encrypted
     * @returns {string}
     */
    static decryptNumber(encrypted) {
      try {
        if (!encrypted || encrypted === "") {
          return "";
        }
  
        // 补全Base64编码（添加等号）
        let paddedEncrypted = encrypted;
        while (paddedEncrypted.length % 4 !== 0) {
          paddedEncrypted += "=";
        }
  
        // Base64解码
        const decoded = this.decode(paddedEncrypted);
        if (decoded.length === 0) {
          return "";
        }
  
        const mapped = new TextDecoder().decode(decoded);
  
        // 反向映射表
        const reverseMapping = {
          k: "0",
          p: "1",
          m: "2",
          n: "3",
          b: "4",
          v: "5",
          c: "6",
          x: "7",
          z: "8",
          l: "9",
        };
  
        // 将字符转回数字
        let result = "";
        for (let char of mapped) {
          if (reverseMapping[char]) {
            result += reverseMapping[char];
          }
        }
  
        return result;
      } catch (e) {
        return ""; // 解析失败时返回空字符串
      }
    }
  
    /**
     * 验证字符串是否为加密后的格式
     * @param {string} str
     * @returns {boolean}
     */
    static isBase64Encrypted(str) {
      if (!str || str.trim() === "" || str.length < 4) {
        return false;
      }
  
      try {
        // 补全Base64编码
        let paddedStr = str;
        while (paddedStr.length % 4 !== 0) {
          paddedStr += "=";
        }
  
        // 验证是否为有效的Base64
        const decoded = this.decode(paddedStr);
        if (decoded.length === 0) {
          return false;
        }
  
        const decodedStr = new TextDecoder().decode(decoded);
  
        // 检查解码后的字符是否都在映射表中
        const validChars = "kpmnbvcxzl";
        let hasValidChar = false;
  
        for (let char of decodedStr) {
          if (validChars.includes(char)) {
            hasValidChar = true;
          } else if (char !== "\0") {
            // 忽略空字符
            return false;
          }
        }
  
        return hasValidChar;
      } catch (e) {
        return false;
      }
    }
  }

  export { Base64Util };